﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System.Text;

public class ScreenManager : DrawableGameComponent
{
    List<GameScreen> screens = new List<GameScreen>();
    List<GameScreen> screensToUpdate = new List<GameScreen>();

    SpriteBatch spriteBatch;
    public SpriteBatch SpriteBatch
    {
        get { return spriteBatch; }
    }

    private static GraphicsDeviceManager graphics;
    public static GraphicsDeviceManager Graphics
    {
        get { return graphics; }
    }

    private Game gameRef;
    public Game GameRef
    {
        get { return gameRef; }
        set { gameRef = value; }
    }

    bool isInitialized;

    public ScreenManager(Game game)
        : base(game)
    {
        gameRef = game;
        graphics = game.graphics;
    }

    public override void Initialize()
    {
        base.Initialize();

        isInitialized = true;
    }

    protected override void LoadContent()
    {
        // Load content belonging to the screen manager.
        ContentManager content = Game.Content;

        spriteBatch = new SpriteBatch(GraphicsDevice);

        // Tell each of the screens to load their content.
        foreach (GameScreen screen in screens)
        {
            screen.LoadContent();
        }
    }

    protected override void UnloadContent()
    {
        // Tell each of the screens to unload their content.
        foreach (GameScreen screen in screens)
        {
            screen.UnloadContent();
        }
    }

    public override void Update(GameTime gameTime)
    {
        // Make a copy of the master screen list, to avoid confusion if
        // the process of updating one screen adds or removes others.
        screensToUpdate.Clear();

        foreach (GameScreen screen in screens)
            screensToUpdate.Add(screen);

        bool otherScreenHasFocus = !Game.IsActive;
        bool coveredByOtherScreen = false;

        // Loop as long as there are screens waiting to be updated.
        while (screensToUpdate.Count > 0)
        {
            // Pop the topmost screen off the waiting list.
            GameScreen screen = screensToUpdate[screensToUpdate.Count - 1];

            screensToUpdate.RemoveAt(screensToUpdate.Count - 1);

            // Update the screen.
            screen.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);

            if (screen.ScreenState == ScreenState.TransitionOn ||
                screen.ScreenState == ScreenState.Active)
            {
                // If this is the first active screen we came across,
                // give it a chance to handle input.
                if (!otherScreenHasFocus)
                {
                    screen.HandleInput();

                    otherScreenHasFocus = true;
                }

                // If this is an active non-popup, inform any subsequent
                // screens that they are covered by it.
                if (!screen.IsPopup)
                    coveredByOtherScreen = true;
            }
        }
    }

    public override void Draw(GameTime gameTime)
    {
        foreach (GameScreen screen in screens)
        {
            if (screen.ScreenState == ScreenState.Hidden)
                continue;

            screen.Draw(gameTime);
        }
    }

    public void AddScreen(GameScreen screen)
    {
        screen.ScreenManager = this;
        screen.IsExiting = false;

        // If we have a graphics device, tell the screen to load content.
        if (isInitialized)
        {
            screen.LoadContent();
        }

        screens.Add(screen);
    }

    public void RemoveAll()
    {
        //foreach (GameScreen screen in screens)
        for (int i = screens.Count - 1; i >= 0; i-- )
        {
            screens[i].ExitScreen();
        }
    }

    public void Debug()
    {
        foreach (GameScreen screen in screens)
        {
            //int a;
        }
    }

    public void MainMenu()
    {
        foreach (GameScreen screen in screens)
        {
            if (!screen.GetType().Name.Equals("MainMenuScreen"))
            {
                screen.ExitScreen();
                AudioManager.PlayMusic();
            }
        }
    }

    public void RemoveScreen(GameScreen screen)
    {
        // If we have a graphics device, tell the screen to unload content.
        if (isInitialized)
        {
            screen.UnloadContent();
        }

        screens.Remove(screen);
        screensToUpdate.Remove(screen);

        if (screens.Count == 0 && screensToUpdate.Count == 0)
        {
            Game.Exit();
        }
    }

    public GameScreen[] GetScreens()
    {
        return screens.ToArray();
    }

}

